package zr.osm;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;

import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.Overlay;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

public class OSMMap extends Activity
{
	public MapView mapView;
	public MapController mapController;
    public GeoPoint point;
    
    double Lon = 0;
    double Lat = 0;
    
    String strUrl = "http://213.103.200.57:8080/zr/trafficweb";
	URL url = null;
	String username ="";
	String password ="";
	
    private LocationManager mlocManager;
	private LocationListener mlocListener = new MyLocationListener();
	private MyOverlay myOverlay = new MyOverlay(null);
	
	public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.osmmap);
        
        /*
         *The followings are all the necessary setting for rendering OSM.
         * */
        mapView = (MapView) this.findViewById(R.id.mapview);        
        mapView.setTileSource(TileSourceFactory.MAPNIK);
        mapView.setBuiltInZoomControls(true);
        mapView.setMultiTouchControls(true);
        mapController = mapView.getController();
        mapController.setZoom(15);
        point = new GeoPoint(59351756, 18057822);
        mapController.setCenter(point);
        
        // get username and password from ZRTrafficActivity.java
        username = ZRTrafficActivity.userName.getText().toString();
    	password = ZRTrafficActivity.passWord.getText().toString();
    	
        /* Use the LocationManager class to obtain GPS locations */
		mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
		mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5*1000, 10, mlocListener);
    }
  
    protected boolean isRouteDisplayed() 
    {
        // TODO Auto-generated method stub
        return false;
    }
    
    // MyLocationListner
	class MyLocationListener implements LocationListener
	{
		public void onLocationChanged(Location loc) 
		{
			// TODO Auto-generated method stub	
			Lon = loc.getLongitude();
			Lat = loc.getLatitude();
			point = new GeoPoint((int)(Lat*1e6), (int)(Lon*1e6));
			mapView.getOverlays().add(myOverlay);
			mapController.animateTo(point);
			
	        //send updated latitude and longitude to the server
			try 
			{				
				url = new URL(strUrl);
				HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
				
				urlConn.setDoInput(true);
				urlConn.setDoOutput(true);
				urlConn.setRequestMethod("POST");
				urlConn.setUseCaches(false);
				urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
				urlConn.setRequestProperty("Charest", "utf-8");
				// to connect to the server side
				urlConn.connect();
				
				DataOutputStream dop = new DataOutputStream(urlConn.getOutputStream());
				dop.writeBytes("point=" + URLEncoder.encode("location","utf-8"));
				//it is essential that to add "&" to separate two strings
				dop.writeBytes("&username=" + URLEncoder.encode(username,"utf-8"));
    			dop.writeBytes("&password=" + URLEncoder.encode(password,"utf-8"));
				dop.writeBytes("&lon=" + URLEncoder.encode(Double.toString(Lon),"utf-8"));
				dop.writeBytes("&lat=" + URLEncoder.encode(Double.toString(Lat),"utf-8"));
				dop.flush();
				dop.close();
				
				DataInputStream dis = new DataInputStream(urlConn.getInputStream());
				String locPassage = dis.readUTF();
				// to disconnect the server side
				urlConn.disconnect();
				if("Succeed".equalsIgnoreCase(locPassage))
				{
					//nothing
				}
			}
			catch (MalformedURLException e) 
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
			catch (IOException e)
			{
				e.printStackTrace();
			}//end of sending updated latitude and longitude to the server
		}

		public void onProviderDisabled(String provider) {
			// TODO Auto-generated method stub
			
		}

		public void onProviderEnabled(String provider) {
			// TODO Auto-generated method stub
			
		}

		public void onStatusChanged(String provider, int status, Bundle extras) {
			// TODO Auto-generated method stub
			
		}
	}/*end of MyLocationListner*/
	
	// displaying the geoPoint
	public class MyOverlay extends Overlay
	{
		public MyOverlay(Context ctx) {
			super(ctx);
			// TODO Auto-generated constructor stub
		}

		@Override
		protected void onDraw(Canvas canvas, MapView mapView)
		{
			// TODO Auto-generated method stub
			Paint paint = new Paint();  
            paint.setColor(Color.RED);
            Point screenPoint = new Point();  
            mapView.getProjection().toPixels(point, screenPoint);  
            Bitmap bmp = BitmapFactory.decodeResource(getResources(),R.drawable.dot);  
            canvas.drawBitmap(bmp, screenPoint.x, screenPoint.y, paint); 
		}

		@Override
		protected void onDrawFinished(Canvas arg0, MapView arg1) {
			// TODO Auto-generated method stub
		}
	}/*end of displaying the geoPoint*/
	
    // add menu
 	public boolean onCreateOptionsMenu(Menu menu) 
 	{
 		MenuInflater inflater = getMenuInflater();
 		inflater.inflate(R.menu.menu, menu);
 		return true;
 	}
 	
 	/* There are six menu events, and they are as follows
 	 * 1. draw the path by the user itself
 	 * 2. draw the shortest path by the system itself when the startPoint and endPoint are defined
 	 * 3. send report when there is a traffic jam
 	 * 4. information about the ZRTraffic
 	 * 5. simple help for using ZRTraffic
 	 * 6. quit the application
 	 * */
	public boolean onOptionsItemSelected(MenuItem item) 
	{
		switch ( item.getItemId() ) 
		{
			case R.id.draw_menu:
				Toast.makeText(this, "You selected DrawPath.",Toast.LENGTH_SHORT).show();
			break;
			case R.id.shortest_menu:	
				new AlertDialog.Builder(this).setTitle("Traffic Jam Report").setIcon(
				     android.R.drawable.ic_dialog_info).setSingleChoiceItems(
				     new String[] { "Mild", "Intermidate", "Severe"}, 0,
				     new DialogInterface.OnClickListener() 
				     {
				    	 public void onClick(DialogInterface dialog, int which) 
				    	 {
				    		 dialog.dismiss();
			    	 	 }
				     }).setPositiveButton("OK", null).show();
			break;
			case R.id.report_menu:
				Toast.makeText(this, "You selected Report.",Toast.LENGTH_SHORT).show();
			break;
			case R.id.about_menu:
				Toast.makeText(this, "You selected About.",Toast.LENGTH_SHORT).show();
			break;
			case R.id.help_menu:
				Toast.makeText(this, "You selected Help.",Toast.LENGTH_SHORT).show();
			break;
			case R.id.quit_menu:
				// create a AlertDialog
				AlertDialog.Builder quit=new AlertDialog.Builder(OSMMap.this);
				// set title
				quit.setTitle("Quit");
				// set content
				quit.setMessage("Sure to quit ZRTraffic?");
				// set positive button
				quit.setPositiveButton("OK", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int i) 
					{
						// TODO Auto-generated method stub						
			    		try 
			    		{				
			    			url = new URL(strUrl);
			    			HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
							
			    			urlConn.setDoInput(true);
			    			urlConn.setDoOutput(true);
			    			urlConn.setRequestMethod("POST");
			    			urlConn.setUseCaches(false);
			    			urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			    			urlConn.setRequestProperty("Charest", "utf-8");
			    			// to connect to the server side
			    			urlConn.connect();

			    			//NOTE!!!- DataOutputStream AND DataInputStream MUST exist at the same time.
			    			DataOutputStream dop = new DataOutputStream(urlConn.getOutputStream());
			    			dop.writeBytes("point=" + URLEncoder.encode("logout","utf-8"));
			    			//it is essential that to add "&" to separate two strings			    			
			    			dop.writeBytes("&username=" + URLEncoder.encode(username,"utf-8"));
			    			dop.writeBytes("&password=" + URLEncoder.encode(password,"utf-8"));
			    			dop.flush();
			    			dop.close();
			    			
			    			DataInputStream dis = new DataInputStream(urlConn.getInputStream());
			    			String logoutPassage = dis.readUTF();
			    			// to disconnect the server side
			    			urlConn.disconnect();
			    			if ("Succeed".equalsIgnoreCase(logoutPassage))
			    			{
			    				//nothing
			    			}			    			
			    		} 
			    		catch (MalformedURLException e) 
			    		{
			    			e.printStackTrace();
			    		} 
			    		catch (IOException e)
			    		{
			    			e.printStackTrace();
			    		}
			    		//NOTE: exit the application
						System.exit(0);
					}
				});
				// set negative button
				quit.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int i) 
					{
						// TODO Auto-generated method stub
						return;
					}
				});
				// show the AlertDialog
				quit.show();
			break;
		}
		return true;
	}/*end of menu events*/
}